/*
 * Copyright (C) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup VideoDecoder
 * @{
 *
 * @brief Provides the functions for video decoding.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 *
 * @since 9
 * @version 1.0
 */

/**
 * @file native_avcodec_videodecoder.h
 *
 * @brief Declares the native APIs used for video decoding.
 *
 * @since 9
 * @version 1.0
 */

#ifndef NATIVE_AVCODEC_VIDEODECODER_H
#define NATIVE_AVCODEC_VIDEODECODER_H

#include <stdint.h>
#include <stdio.h>
#include "native_averrors.h"
#include "native_avformat.h"
#include "native_avmemory.h"
#include "native_avcodec_base.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Creates a video decoder instance based on a Multipurpose Internet Mail Extension (MIME) type.
 * This API is recommended in most cases.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param mime Indicates the pointer to a MIME type. For details, see {@link OH_AVCODEC_MIMETYPE_VIDEO_AVC}.
 * @return Returns the pointer to an <b>OH_AVCodec</b> instance.
 * @since 9
 * @version 1.0
 */
OH_AVCodec *OH_VideoDecoder_CreateByMime(const char *mime);

/**
 * @brief Creates a video decoder instance based on a video decoder name. 
 * To use this API, you must know the exact name of the video decoder.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param name Indicates the pointer to a video decoder name.
 * @return Returns the pointer to an <b>OH_AVCodec</b> instance.
 * @since 9
 * @version 1.0
 */
OH_AVCodec *OH_VideoDecoder_CreateByName(const char *name);

/**
 * @brief Clears the internal resources of a video decoder and destroys the video decoder instance.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_Destroy(OH_AVCodec *codec);

/**
 * @brief Sets an asynchronous callback so that your application can respond to events generated by a video decoder.
 * This API must be called prior to <b>Prepare</b>.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @param callback Indicates a collection of all callback functions. For details, see {@link OH_AVCodecAsyncCallback}.
 * @param userData Indicates the pointer to user-specific data.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_SetCallback(OH_AVCodec *codec, OH_AVCodecAsyncCallback callback, void *userData);

/**
 * @brief Sets an output surface for a video decoder. This API must be called prior to <b>Prepare</b>.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @param window Indicates the pointer to an <b>OHNativeWindow</b> instance.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_SetSurface(OH_AVCodec *codec, OHNativeWindow *window);

/**
 * @brief Configures a video decoder. Typically, you need to configure the attributes,
 * which can be extracted from the container, of the video track that can be decoded.
 * This API must be called prior to <b>Prepare</b>.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @param format Indicates the handle to an <b>OH_AVFormat</b> instance,
 * which provides the attributes of the video track to be decoded.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_Configure(OH_AVCodec *codec, OH_AVFormat *format);

/**
 * @brief Prepares internal resources for a video decoder. This API must be called after <b>Configure</b>.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_Prepare(OH_AVCodec *codec);

/**
 * @brief Starts a video decoder. This API can be called only after the decoder is prepared successfully.
 * After being started, the decoder starts to report the {@link OH_AVCodecOnNeedInputData} event.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_Start(OH_AVCodec *codec);

/**
 * @brief Stops a video decoder. After the decoder is stopped, you can call <b>Start</b> to start it again.
 * If you have passed codec-specific data in the previous <b>Start</b> for the decoder, you must pass it again.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_Stop(OH_AVCodec *codec);

/**
 * @brief Clears the input and output data in the internal buffer of a video decoder. 
 * This API invalidates the indexes of all buffers previously reported through the asynchronous callback.
 * Therefore, before calling this API, ensure that the buffers corresponding to the indexes are no longer required.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_Flush(OH_AVCodec *codec);

/**
 * @brief Resets a video decoder. To continue decoding, you must call <b>Configure</b> and <b>Start</b>
 * to configure and start the decoder again.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_Reset(OH_AVCodec *codec);

/**
 * @brief Obtains the attributes of the output data of a video decoder. The <b>OH_AVFormat</b> instance
 * in the return value will become invalid when this API is called again or 
 * when the <b>OH_AVCodec</b> instance is destroyed.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @return Returns the pointer to an <b>OH_AVFormat</b> instance.
 * @since 9
 * @version 1.0
 */
OH_AVFormat *OH_VideoDecoder_GetOutputDescription(OH_AVCodec *codec);

/**
 * @brief Sets dynamic parameters for a video decoder. This API can be called only after the decoder is started.
 * Incorrect parameter settings may cause decoding failure.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @param format Indicates the handle to an <b>OH_AVFormat</b> instance.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_SetParameter(OH_AVCodec *codec, OH_AVFormat *format);

/**
 * @brief Pushes the input buffer filled with data to a video decoder. The {@link OH_AVCodecOnNeedInputData} callback
 * reports available input buffers and their indexes. After being pushed to the decoder, a buffer is not accessible until
 * the buffer with the same index is reported again through the {@link OH_AVCodecOnNeedInputData} callback. 
 * In addition, some decoders require the input of codec-specific data, such as PPS/SPS data in H.264 format,
 * to initialize the decoding process.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @param index Indicates the index of an input buffer.
 * @param attr Indicates the attributes of the data contained in the buffer.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_PushInputData(OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr);

/**
 * @brief Frees an output buffer of a video decoder and instructs the decoder to render the decoded data in the buffer
 * on the output surface. If no output surface is configured, calling this API only frees the output buffer.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @param index Indicates the index of an output buffer.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_RenderOutputData(OH_AVCodec *codec, uint32_t index);

/**
 * @brief Frees an output buffer of a video decoder.
 * 
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @param codec Indicates the pointer to an <b>OH_AVCodec</b> instance.
 * @param index Indicates the index of an output buffer.
 * @return Returns <b>AV_ERR_OK</b> if the operation is successful.
 * @return Returns an error code defined in {@link OH_AVErrCode} if the operation fails.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoDecoder_FreeOutputData(OH_AVCodec *codec, uint32_t index);

#ifdef __cplusplus
}
#endif

#endif // NATIVE_AVCODEC_VIDEODECODER_H
